﻿@inject IState<AuthMethodsState> authMethodsState
@inject IDispatcher dispatcher
@inherits Fluxor.Blazor.Web.Components.FluxorComponent
@using SimpleIdServer.IdServer.Website.Resources;
@using SimpleIdServer.IdServer.Api.AuthenticationMethods
@using SimpleIdServer.IdServer.Website.Stores.AuthMethodsStore;

@if (authMethodsState.Value != null && !authMethodsState.Value.IsLoading)
{
    <RadzenRow>
        <!-- Filter the authentication methods by their capabilities -->
        <RadzenColumn>
            <RadzenFormField Text="@Global.AuthMethodCapabilities" Variant=Variant.Outlined>
                <ChildContent>
                    <RadzenDropDown Data=@AllAuthenticationMethods
                                    TextProperty="Name"
                                    ValueProperty="Capability"
                                    Multiple=true
                                    AllowClear=true
                                    Chips=true
                                    @bind-Value=@SelectedAuthenticationMethods
                                    Change=@((obj) => UpdateAuthenticationMethod(obj)) />
                </ChildContent>
                <Helper>
                    <RadzenText TextStyle="TextStyle.Caption">@Global.FilterAuthMethodByCapabilities</RadzenText>
                </Helper>
            </RadzenFormField>
        </RadzenColumn>
        <!-- Legend -->
        <RadzenColumn>
            <RadzenText class="no-margin" Text="@Global.Legend" TextStyle="TextStyle.DisplayH6" />
            <table>
                <tbody>
                    <tr>
                        <td><RadzenBadge BadgeStyle="BadgeStyle.Info" Variant="Variant.Outlined">@Global.Authentication</RadzenBadge></td>
                        <td>@Global.SupportUserAuthentication</td>
                    </tr>
                    <tr>
                        <td><RadzenBadge BadgeStyle="BadgeStyle.Info" Variant="Variant.Outlined">@Global.Registration</RadzenBadge></td>
                        <td>@Global.SupportUserRegistration</td>
                    </tr>
                    <tr>
                        <td><RadzenBadge BadgeStyle="BadgeStyle.Info" Variant="Variant.Outlined">@Global.PushNotification</RadzenBadge></td>
                        <td>@Global.SupportPushNotification</td>
                    </tr>
                </tbody>
            </table>
        </RadzenColumn>
    </RadzenRow>

    <RadzenRow class="rz-pt-12">
        @foreach (var authMethod in authMethods.Where(a => a.Name != "otp"))
        {
            var link = GetAuthMethodUrl(authMethod);
            if (!string.IsNullOrWhiteSpace(link))
            {
                <RadzenColumn Size="12" SizeMD="4">
                    <RadzenLink Path="@link">
                        <RadzenCard Variant="Variant.Filled">
                            <RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Start">
                                <RadzenImage Path="@GetPicture(authMethod)" Style="height: 60px"></RadzenImage>
                                <RadzenText TextStyle="TextStyle.DisplayH6">@authMethod.Name</RadzenText>
                                @if(SelectedAuthenticationMethods != null)
                                {
                                    <div>
                                        @if (authMethod.Capabilities.HasFlag(AuthenticationMethodCapabilities.USERAUTHENTICATION))
                                        {
                                            <RadzenBadge BadgeStyle="@(SelectedAuthenticationMethods.Any(a => a.HasFlag(AuthenticationMethodCapabilities.USERAUTHENTICATION)) ? BadgeStyle.Primary : BadgeStyle.Info)" Variant="Variant.Outlined">@Global.Authentication</RadzenBadge>
                                        }

                                        @if (authMethod.Capabilities.HasFlag(AuthenticationMethodCapabilities.PUSHNOTIFICATION))
                                        {
                                            <RadzenBadge BadgeStyle="@(SelectedAuthenticationMethods.Any(a => a.HasFlag(AuthenticationMethodCapabilities.PUSHNOTIFICATION)) ? BadgeStyle.Primary : BadgeStyle.Info)" Variant="Variant.Outlined">@Global.PushNotification</RadzenBadge>
                                        }

                                        @if (authMethod.Capabilities.HasFlag(AuthenticationMethodCapabilities.USERREGISTRATION))
                                        {
                                            <RadzenBadge BadgeStyle="@(SelectedAuthenticationMethods.Any(a => a.HasFlag(AuthenticationMethodCapabilities.USERREGISTRATION)) ? BadgeStyle.Primary : BadgeStyle.Info)" Variant="Variant.Outlined">@Global.Registration</RadzenBadge>
                                        }
                                    </div>
                                }
                            </RadzenStack>
                        </RadzenCard>
                    </RadzenLink>
                </RadzenColumn>
            }
            else
            {
                <RadzenColumn Size="12" SizeMD="4">
                    <RadzenCard Variant="Variant.Filled">
                        <RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Start">
                            <RadzenImage Path="@GetPicture(authMethod)" Style="height: 60px"></RadzenImage>
                            <RadzenText TextStyle="TextStyle.DisplayH6">@authMethod.Name</RadzenText>
                            @if(SelectedAuthenticationMethods != null)
                            {
                                <div>
                                    @if (authMethod.Capabilities.HasFlag(AuthenticationMethodCapabilities.USERAUTHENTICATION))
                                    {
                                        <RadzenBadge BadgeStyle="@(SelectedAuthenticationMethods.Any(a => a.HasFlag(AuthenticationMethodCapabilities.USERAUTHENTICATION)) ? BadgeStyle.Primary : BadgeStyle.Info)" Variant="Variant.Outlined">@Global.Authentication</RadzenBadge>
                                    }

                                    @if (authMethod.Capabilities.HasFlag(AuthenticationMethodCapabilities.PUSHNOTIFICATION))
                                    {
                                        <RadzenBadge BadgeStyle="@(SelectedAuthenticationMethods.Any(a => a.HasFlag(AuthenticationMethodCapabilities.PUSHNOTIFICATION)) ? BadgeStyle.Primary : BadgeStyle.Info)" Variant="Variant.Outlined">>@Global.PushNotification</RadzenBadge>
                                    }

                                    @if (authMethod.Capabilities.HasFlag(AuthenticationMethodCapabilities.USERREGISTRATION))
                                    {
                                        <RadzenBadge BadgeStyle="@(SelectedAuthenticationMethods.Any(a => a.HasFlag(AuthenticationMethodCapabilities.USERREGISTRATION)) ? BadgeStyle.Primary : BadgeStyle.Info)" Variant="Variant.Outlined">>@Global.Registration</RadzenBadge>
                                    }
                                </div>
                            }
                        </RadzenStack>
                    </RadzenCard>
                </RadzenColumn>
            }
        }
    </RadzenRow>
}

@code {
    IEnumerable<AuthenticationMethodResult> fullAuthMethods;
    IEnumerable<AuthenticationMethodResult> authMethods = new List<AuthenticationMethodResult>();

    record AuthenticationMethodCapability
    {
        public string Name { get; set; }
        public AuthenticationMethodCapabilities Capability { get; set; }
    }

    List<AuthenticationMethodCapability> AllAuthenticationMethods { get; set; } = new List<AuthenticationMethodCapability>
    {
        new AuthenticationMethodCapability { Name = Global.Authentication, Capability = AuthenticationMethodCapabilities.USERAUTHENTICATION },
        new AuthenticationMethodCapability { Name = Global.Registration, Capability = AuthenticationMethodCapabilities.USERREGISTRATION },
        new AuthenticationMethodCapability { Name = Global.PushNotification, Capability = AuthenticationMethodCapabilities.PUSHNOTIFICATION }
    };

    List<AuthenticationMethodCapabilities> SelectedAuthenticationMethods { get; set; } = new List<AuthenticationMethodCapabilities>
    {
        AuthenticationMethodCapabilities.USERAUTHENTICATION,
        AuthenticationMethodCapabilities.USERREGISTRATION,
        AuthenticationMethodCapabilities.PUSHNOTIFICATION
    };

    protected override void OnAfterRender(bool firstRender)
    {
        base.OnAfterRender(firstRender);
        if(firstRender)
        {
            SubscribeToAction<GetAllAuthMethodSuccessAction>((act) =>
            {
                fullAuthMethods = act.AuthMethods;
                authMethods = act.AuthMethods;
            });
            var act = new GetAllAuthMethodAction();
            dispatcher.Dispatch(act);
        }
    }

    string GetAuthMethodUrl(AuthenticationMethodResult authMethod)
    {
        if (string.IsNullOrWhiteSpace(authMethod.OptionsName)) return null;
        return "/authentications/authmethods/" + authMethod.Id + "/options";
    }

    string GetPicture(AuthenticationMethodResult authMethod)
    {
        var result = "_content/SimpleIdServer.IdServer.Website/images";
        switch(authMethod.Id)
        {
            case "email":
                return result + "/email.png";
            case "sms":
                return result + "/sms.png";
            case "webauthn":
                return result + "/fido.png";
            case "mobile":
                return result + "/mobile.png";
            case "firebase":
                return result + "/firebase.png";
            case "console":
                return result + "/MachineClient.png";
            case "otp":
                return result + "/OTP.png";
            case "gotify":
                return result + "/gotify.png";
            case "vp":
                return result + "/Wallet.png";
            default:
                return result + "/pwd.png";
        }
    }

    void UpdateAuthenticationMethod(object obj)
    {
        var selectedCapabilities = (IEnumerable<AuthenticationMethodCapabilities>)obj ?? new List<AuthenticationMethodCapabilities>();
        authMethods = fullAuthMethods.Where(a => selectedCapabilities.Any(c => a.Capabilities.HasFlag(c)));
    }
}